/**
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package us.levk.remote.drmaa.server.xmlrpc;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.ggf.drmaa.DrmaaException;
import org.ggf.drmaa.FileTransferMode;
import org.ggf.drmaa.InvalidJobTemplateException;
import org.ggf.drmaa.JobTemplate;
import org.ggf.drmaa.PartialTimestamp;

import us.levk.remote.drmaa.common.api.RemoteTemplate;

/**
 * @author levk
 *
 */
public class JobTemplateImpl implements RemoteTemplate {
  private static final long serialVersionUID = 1L;

  private static final transient Logger LOG = Logger.getLogger (JobTemplateImpl.class);

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setRemoteCommand(java.util.UUID, java.lang.String)
   */
  @Override public void setRemoteCommand (UUID template, String remoteCommand) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setRemoteCommand (remoteCommand);
    LOG.trace ("Set remote command for template " + template + " to " + remoteCommand);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getRemoteCommand(java.util.UUID)
   */
  @Override public String getRemoteCommand (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getRemoteCommand ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setArgs(java.util.UUID, java.util.List)
   */
  @Override public void setArgs (UUID template, List<?> args) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setArgs (args);
    LOG.trace ("Set command arguments for template " + template + " to " + args);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getArgs(java.util.UUID)
   */
  @Override public List<?> getArgs (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getArgs ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setJobSubmissionState(java.util.UUID, int)
   */
  @Override public void setJobSubmissionState (UUID template, int state) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setJobSubmissionState (state);
    LOG.trace ("Set job submission state for template " + template + " to " + state);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getJobSubmissionState(java.util.UUID)
   */
  @Override public int getJobSubmissionState (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getJobSubmissionState ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setJobEnvironment(java.util.UUID, java.util.Map)
   */
  @Override public void setJobEnvironment (UUID template, Map<?, ?> env) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setJobEnvironment (env);
    LOG.trace ("Set job environment for template " + template + " to " + env);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getJobEnvironment(java.util.UUID)
   */
  @Override public Map<?, ?> getJobEnvironment (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getJobEnvironment ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setWorkingDirectory(java.util.UUID, java.lang.String)
   */
  @Override public void setWorkingDirectory (UUID template, String wd) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setWorkingDirectory (wd);
    LOG.trace ("Set working directory for template " + template + " to " + wd);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getWorkingDirectory(java.util.UUID)
   */
  @Override public String getWorkingDirectory (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getWorkingDirectory ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setJobCategory(java.util.UUID, java.lang.String)
   */
  @Override public void setJobCategory (UUID template, String category) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setJobCategory (category);
    LOG.trace ("Set job category for template " + template + " to " + category);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getJobCategory(java.util.UUID)
   */
  @Override public String getJobCategory (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getJobCategory ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setNativeSpecification(java.util.UUID, java.lang.String)
   */
  @Override public void setNativeSpecification (UUID template, String spec) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setNativeSpecification (spec);
    LOG.trace ("Set native specification for template " + template + " to " + spec);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getNativeSpecification(java.util.UUID)
   */
  @Override public String getNativeSpecification (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getNativeSpecification ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setEmail(java.util.UUID, java.util.Set)
   */
  @Override public void setEmail (UUID template, Set<?> email) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setEmail (email);
    LOG.trace ("Set email for template " + template  + " to " + email);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getEmail(java.util.UUID)
   */
  @Override public Set<?> getEmail (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getEmail ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setBlockEmail(java.util.UUID, boolean)
   */
  @Override public void setBlockEmail (UUID template, boolean blockEmail) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setBlockEmail (blockEmail);
    LOG.trace ((blockEmail ? "S" : "Uns") + "et blocking email for template " + template);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getBlockEmail(java.util.UUID)
   */
  @Override public boolean getBlockEmail (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getBlockEmail ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setStartTime(java.util.UUID, org.ggf.drmaa.PartialTimestamp)
   */
  @Override public void setStartTime (UUID template, PartialTimestamp startTime) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setStartTime (startTime);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getStartTime(java.util.UUID)
   */
  @Override public PartialTimestamp getStartTime (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getStartTime ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setJobName(java.util.UUID, java.lang.String)
   */
  @Override public void setJobName (UUID template, String name) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setJobName (name);
    LOG.trace ("Set job name for template " + template + " to " + name);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getJobName(java.util.UUID)
   */
  @Override public String getJobName (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getJobName ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setInputPath(java.util.UUID, java.lang.String)
   */
  @Override public void setInputPath (UUID template, String inputPath) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setInputPath (inputPath);
    LOG.trace ("Set input path for template " + template + " to " + inputPath);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getInputPath(java.util.UUID)
   */
  @Override public String getInputPath (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getInputPath ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setOutputPath(java.util.UUID, java.lang.String)
   */
  @Override public void setOutputPath (UUID template, String outputPath) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setOutputPath (outputPath);
    LOG.trace ("Set output path for template " + template + " to " + outputPath);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getOutputPath(java.util.UUID)
   */
  @Override public String getOutputPath (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getOutputPath ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setErrorPath(java.util.UUID, java.lang.String)
   */
  @Override public void setErrorPath (UUID template, String errorPath) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setErrorPath (errorPath);
    LOG.trace ("Set error path for template " + template + " to " + errorPath);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getErrorPath(java.util.UUID)
   */
  @Override public String getErrorPath (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getErrorPath ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setJoinFiles(java.util.UUID, boolean)
   */
  @Override public void setJoinFiles (UUID template, boolean join) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setJoinFiles (join);
    LOG.trace ((join ? "S" : "Uns") + "et join files for template " + template);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getJoinFiles(java.util.UUID)
   */
  @Override public boolean getJoinFiles (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getJoinFiles ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setTransferFiles(java.util.UUID, org.ggf.drmaa.FileTransferMode)
   */
  @Override public void setTransferFiles (UUID template, FileTransferMode mode) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setTransferFiles (mode);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getTransferFiles(java.util.UUID)
   */
  @Override public FileTransferMode getTransferFiles (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getTransferFiles ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setDeadlineTime(java.util.UUID, org.ggf.drmaa.PartialTimestamp)
   */
  @Override public void setDeadlineTime (UUID template, PartialTimestamp deadline) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setDeadlineTime (deadline);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getDeadlineTime(java.util.UUID)
   */
  @Override public PartialTimestamp getDeadlineTime (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getDeadlineTime ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setHardWallclockLimit(java.util.UUID, long)
   */
  @Override public void setHardWallclockLimit (UUID template, long hardWallclockLimit) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setHardWallclockTimeLimit (hardWallclockLimit);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getHardWallclockLimit(java.util.UUID)
   */
  @Override public long getHardWallclockLimit (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getHardWallclockTimeLimit ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setSoftWallclockLimit(java.util.UUID, long)
   */
  @Override public void setSoftWallclockLimit (UUID template, long softWallclockLimit) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setSoftWallclockTimeLimit (softWallclockLimit);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getSoftWallclockLimit(java.util.UUID)
   */
  @Override public long getSoftWallclockLimit (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getSoftWallclockTimeLimit ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setHardRunDurationLimit(java.util.UUID, long)
   */
  @Override public void setHardRunDurationLimit (UUID template, long hardRunLimit) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setHardRunDurationLimit (hardRunLimit);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getHardRunDurationLimit(java.util.UUID)
   */
  @Override public long getHardRunDurationLimit (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getHardRunDurationLimit ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#setSoftRunDurationLimit(java.util.UUID, long)
   */
  @Override public void setSoftRunDurationLimit (UUID template, long softRunLimit) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    jt.setSoftRunDurationLimit (softRunLimit);
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getSoftRunDurationLimit(java.util.UUID)
   */
  @Override public long getSoftRunDurationLimit (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getSoftRunDurationLimit ();
  }

  /* (non-Javadoc)
   * @see us.levk.remote.drmaa.common.RemoteTemplate#getAttributeName(java.util.UUID)
   */
  @Override public Set<?> getAttributeName (UUID template) throws DrmaaException {
    JobTemplate jt = Instances.TEMPLATES.get (template);
    if (jt == null) throw new InvalidJobTemplateException ();
    return jt.getAttributeNames ();
  }
}
